import random
from typing import Dict

from gui.utils import ENV_DESC
from state.building import Building, BUILDING_MAP
from state.reference import BLOCK_ENV_PRODUCE_OFFSET


def _gen_block_produce(env):
    offset = BLOCK_ENV_PRODUCE_OFFSET[env + 2]
    result = [random.randint(*offset) for _ in range(3)]
    return {
        r: result[i]
        for i, r in enumerate(('energy', 'mineral', 'food')) if result[i] > 0
    }


class WorldBlock:
    def __init__(self, row, col, env):
        self.row = row
        self.col = col
        self.env = env
        self.pos = row, col

        self.z_number = random.randint(3, 5)
        self.player: str | None = None

        self.zoning_map = {
            (i, j): ZoningBlock(i, j, self)
            for i in range(self.z_number) for j in range(self.z_number)
        }

        self.produce = _gen_block_produce(env)

    def __str__(self):
        return f"<WorldBlock: {self.row}, {self.col}>"

    def info(self):
        msg = f'坐标: {self.pos}\n'
        msg += f'环境: {ENV_DESC[self.env + 2]}'

        return msg

    def neighbors(self, b_map: Dict | None = None):
        if b_map is None:
            for offset in ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)):
                yield self.row + offset[0], self.col + offset[1]
        else:
            for offset in ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)):
                if b := b_map.get((self.row + offset[0], self.col + offset[1])):
                    yield b


class ZoningBlock:
    def __init__(self, row, col, block: WorldBlock):
        self.row = row
        self.col = col
        self.block = block

        self.building: str | None = None
        self.occupied: str | None = None

    def info(self):
        msg = f'坐标: {(self.row, self.col)}\n'
        msg += f'地块坐标: {self.block.pos}'

        if self.occupied is not None:
            build: Building = BUILDING_MAP[self.occupied]
            msg += f'\n该区划被【{build.desc}】占用'
            return msg

        if self.building is not None:
            build: Building = BUILDING_MAP[self.building]
            msg += f'\n建筑: {build.desc}'

        return msg
